<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>闭包</title>
  </head>
  <body>
    <script>
      /*
         闭包
            -函数和其周围的状态的引用捆绑在一起形成闭包
            -可以在另一个作用域中调用一个函数内部的函数并访问到函数作用域中的成员
            -函数在执行的时候回放到一个执行栈上当函数执行完毕后会被移除，但是堆上
             的作用域成员因为被外部使用不能释放，因此内部函数依然可以访问外部函数
             成员
            -延长了函数内部成员的作用范围
        */
      //   应用1 执行移除的函数
      function once(fn) {
        let done = false;
        return function () {
          if (!done) {
            done = true;
            return fn.apply(this, arguments);
          }
        };
      }
      let pay = once(function (money) {
        console.log("支付：" + money);
      });
      pay(5);
      pay(5);
      pay(5);
      pay(5);

      //应用2  求幂函数
      function makePower(power) {
        return function (numbers) {
          return Math.pow(numbers, power);
        };
      }
      //求平方
      let p2 = makePower(2);
      console.log(p2(4));

      //应用3 求员工工资
      function makeSalary(base) {
        return function (performance) {
          return base + performance;
        };
      }
      let level1 = makeSalary(10000);
      let level2 = makeSalary(12000);
      console.log(level1(4000));
      console.log(level2(3000));
    </script>
  </body>
</html>
